﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace IAnalyze
{
    /// <summary>
    /// 开始识别事件的参数
    /// </summary>
    public class EventArgsAnalyzeBegin : EventArgs
    {   
        /// <summary>
        /// 报警帧组ID
        /// </summary>
        public readonly long GroupID;
        /// <summary>
        /// 每组识别总帧数
        /// </summary>
        public readonly int AnalyzeCount;   
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="count"> 每组要识别的帧数</param>
        public EventArgsAnalyzeBegin(int count)
        {
            GroupID = DateTime.Now.Ticks;
            this.AnalyzeCount = count;
        }
    }
    /// <summary>
    ///  开始报警事件的参数
    /// </summary>
    public class EventArgsAnalyzeAlarm : EventArgs
    {
        /// <summary>
        /// 报警帧组ID
        /// </summary>
        public readonly long GroupID;   
        /// <summary>
        /// 报警帧组中序号
        /// </summary>
        public readonly int FrameIndex;     
        /// <summary>
        /// 报警帧
        /// </summary>
        public readonly Bitmap AlarmFrame; 
        /// <summary>
        /// 报警时间
        /// </summary>
        public readonly DateTime AlarmTime; 
        /// <summary>
        /// 报警区域组
        /// </summary>
        public readonly Rectangle[] AlarmRegion;
        /// <summary>
        /// 报警区域类型组
        /// </summary>
        public readonly int[] AlarmRegionType;

        /// <summary>
        /// 识别报警事件参数
        /// </summary>
        /// <param name="groupID">报警帧组ID</param>
        /// <param name="frameCount">每组报警帧数</param>
        /// <param name="frameIndex">报警帧组中序号</param>
        /// <param name="alarmFrame">报警帧</param>
        /// <param name="alarmTime">报警时间</param>
        /// <param name="alarmRegion">报警区域组</param>
        /// <param name="alarmRegionType">报警区域类型组</param>
        public EventArgsAnalyzeAlarm(long groupID, int frameIndex, Bitmap alarmFrame, DateTime alarmTime, Rectangle[] alarmRegion, int[] alarmRegionType)
            : base()
        {
            this.GroupID = groupID;
            this.FrameIndex = frameIndex;
            this.AlarmFrame = alarmFrame;
            this.AlarmTime = alarmTime;
            this.AlarmRegion = alarmRegion;
            this.AlarmRegionType = alarmRegionType;
        }
    }
    /// <summary>
    /// 识别结束事件的参数
    /// </summary>
    public class EventArgsAnalyzeEnd : EventArgs
    {
        /// <summary>
        /// 报警帧组ID
        /// </summary>
        public readonly long GroupID;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="groupID">报警帧组ID</param>
        public EventArgsAnalyzeEnd(long groupID)
        {
            this.GroupID = groupID;
        }
    }
    /// <summary>
    /// 识别策略接口
    /// </summary>
    public interface IAnalyzeStrategy
    {
        /// <summary>
        /// 开始识别事件
        /// </summary>
        event EventHandler<EventArgsAnalyzeBegin> AnalyzeBegin;
        /// <summary>
        /// 识别报警事件
        /// </summary>
        event EventHandler<EventArgsAnalyzeAlarm> AnalyzeAlarm;
        /// <summary>
        /// 识别结束事件
        /// </summary>
        event EventHandler<EventArgsAnalyzeEnd> AnalyzeEnd;

        /// <summary>
        /// 两个识别帧之间跳过的帧数
        /// </summary>
        int FrameSkipRate { get; }

        /// <summary>
        /// 对一组视频连续的帧除去跳过的帧之后还剩下的帧数
        /// </summary>
        int FrameAnalyzeCount { get; }

        /// <summary>
        /// 报警阈值
        ///     对一组视频帧进行识别
        ///     报警帧数达到阈值前将报警帧进行缓存
        ///     当报警帧数达到此阈值时
        ///         先将缓存报警帧抛出
        ///         再清空缓存
        ///         接下来的报警帧直接抛出，直到该组识别完毕
        ///     如一组视频帧识别完毕也未达到阈值
        ///         清空缓存
        /// </summary>
        int FrameAlarmThreshold { get; }

        /// <summary>
        /// 识别模块
        /// </summary>
        IAnalyze Analyze { set; }

        /// <summary>
        /// 帧图像的宽度
        /// </summary>
        int Width { get;}

        /// <summary>
        ///帧图像的高度
        /// </summary>
        int Height { get;}


        /// <summary>
        /// 输入视频流
        /// </summary>
        /// <param name="stream">视频流</param>
        /// <param name="width">视频宽度</param>
        /// <param name="height">视频调度</param>
        void InputVideoStream(IntPtr stream, int width, int height);

        /// <summary>
        /// 同步开启识别策略
        /// </summary>
        void SyncStartAnalyzeStrategy();

        /// <summary>
        /// 同步停止识别策略
        /// </summary>
        void SyncStopAnalyzeStrategy(int millsecondsTimeout);
    }
}
